﻿using System;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using T.FAS.Runtime.Metadata.Entity;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.FAS.Runtime.Base.Entity;

namespace T.FAS.Runtime.DataModel.Dao
{
    /// <summary>
    /// 实体类check工具
    /// </summary>
    public class EntityCheckTools
    {
        /*IMetaDataContent内基础元数据部分*/
        private const string metaDataID = "MetaDataID";
        private const string metaDataCode = "MetaDataCode";
        private const string metaDataName = "MetaDataName";
        private const string creator = "Creator";
        private const string createTime = "CreateTime";
        private const string lastModifier = "LastModifier";
        private const string lastModifyTime = "LastModifyTime";
        private static object s_lockObj = new object();
        private static List<string> s_keyWords;
        public static List<string> KeyWords
        {
            get
            {
                if (s_keyWords == null)
                {
                    lock (s_lockObj)
                    {
                        s_keyWords = new List<string>();
                        Type trecord = typeof(TRecord);
                        BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public;
                        var fName = trecord.GetFields(bindingFlags)?.Select(f => f.Name);
                        var pName = trecord.GetProperties(bindingFlags)?.Select(p => p.Name);
                        if (fName != null && fName.Count() > 0)
                            s_keyWords.AddRange(fName);
                        if (pName != null && pName.Count() > 0)
                            s_keyWords.AddRange(pName);
                    }
                }
                return s_keyWords;
            }
        }

        private static Func<IMetaDataContent, string, AttributeCheckResult> s_systemFieldValidator = (metadata, attr) =>
        {
            Type t = typeof(IMetaDataContent);
            PropertyInfo property = t.GetProperty(attr);
            object value = property.GetValue(metadata);
            AttributeCheckResult result = new AttributeCheckResult
            {
                CheckResult = true,
                AttrName = attr,
            };
            if ((property.PropertyType == typeof(string) && string.IsNullOrEmpty(value as string)) || value == null)
            { 
                result.CheckResult = false;
                result.ErrorMsg = $"元数据Code:{metadata.MetaDataCode},ID:{metadata.MetaDataID}的系统字段:{attr}不能为空!\r\n";
            }
            return result;
        };

        private static Dictionary<string, Func<IMetaDataContent, string, AttributeCheckResult>> s_systemFieldChecker = new Dictionary<string, Func<IMetaDataContent, string, AttributeCheckResult>>
        {
            //暂时不校验MetaDataID Code Name
            //{MetaDataID, SystemFieldValidator},
            //{MetaDataCode , SystemFieldValidator},
            //{MetaDataName , SystemFieldValidator},
            {creator, s_systemFieldValidator },
            {createTime,s_systemFieldValidator},
            {lastModifier, s_systemFieldValidator },
            {lastModifyTime, s_systemFieldValidator},
        }; 

        /// <summary>
        /// 新增时填充系统字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        public static CheckResult CheckSystemFields(IMetaDataContent content)
        {
            try
            {
                CheckResult checkResult = new CheckResult
                {
                    Result = true,
                    ErrorMsg = "",
                };
                StringBuilder errorBuilder = new StringBuilder(); 
                foreach (var systemField in s_systemFieldChecker.Keys)
                { 
                    AttributeCheckResult attrCheckResult = s_systemFieldChecker[systemField](content, systemField);
                    if(attrCheckResult.CheckResult == false)
                    {
                        checkResult.Result = false;
                        errorBuilder.Append(attrCheckResult.ErrorMsg);
                    }
                }
                checkResult.ErrorMsg = errorBuilder.ToString();
                return checkResult;
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.ValidError, "Check系统字段失败", e);
            }
        }

       
    }
 
    public class CheckResult
    { 
        public bool Result { get; set; }
        public string ErrorMsg { get; set; }
    }

    public class AttributeCheckResult
    {
        /// <summary>
        /// 属性名
        /// </summary>
        public string AttrName { get; set; }
        /// <summary>
        /// true: 验证通过; false: 验证失败
        /// </summary>
        public bool CheckResult { get; set; }
        /// <summary>
        /// 验证提示信息
        /// </summary>
        public string ErrorMsg { get; set; }
    }

   
}
